﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.RobotJog.CApRJRobotJogManipulationLogic
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.RobotJog.Collision;
using EngineeringInternalExtension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.Olp;
using Tecnomatix.Engineering.Olp.OLP_Utilities;
using Tecnomatix.Engineering.Ui.WPF;


namespace DnProcessSimulateCommands.RobotJog;

public class CApRJRobotJogManipulationLogic : INotifyPropertyChanged
{
  private CApRJRobotJogClipboard _clipboard = new CApRJRobotJogClipboard();
  private TxOlpControllerUtilities _controllerUtils = new TxOlpControllerUtilities();
  private TxPlacementManipulator _manipulator;
  private TxPlacementManipulatorParameters _placementParameters;
  private TxOlpRobotFollowMode _followMode;
  private UpdateDelta _updateDelta;
  private ResetManipulatorControl _resetManipulatorControl;
  private CApRJRobotJogCollisionLogic _collisionLogic;
  private bool _lockTCPF;
  private bool _enableRobotPlacement;
  private bool _moveObjectsThatRobotIsAttachedTo;
  private bool _isConfigurationLocked;
  private bool _isManipulationFromInsideCommand;
  private ITxLocatableObject _movingObject;
  private string _selectedConfiguration = "";
  private bool _ignoreKinematicMovedEvent;
  private ObservableCollection<string> _RobotConfigurations;
  private Dictionary<string, TxPoseData> _RobotConfigurationsDict;
  private CApRJRobotJogRotationCircleManager _rotationCircle;
  private TxFrame _referenceFrame;
  private bool _isMovingObjectChanged;
  internal bool _isFreezed;
  private bool _isObjectMovedFromOutside = true;
  private TxTransformation[] _savedLocations;
  private TxRobotExternalAxisData[] _savedExternalAxisData;
  private List<ITxObjectCollection> _pathToRoot;
  private bool _isAbsoluteLocationChangedFired = true;
  private CApRJRobotState _currentRobotState;
  private ForceExit _forceExit;
  private TxObject_DeletedEventHandler _objectDeleted;
  private double _rotationStepSize;
  private double _translationStepSize;
  private bool _snapToStepSize;
  private bool _isManipulatorActive;
  private TxTransformation _tcpfTxTransformationChange;
  private int _disableTcpTrackingModeCounter;
  private bool _isTcpfMovable = true;
  private CApRJRobotJogMovementCache _cache;
  private readonly CApRJSRobotsManager _robotsManager;
  private TxTransformation m_referenceFrameLastLocation;
  private string m_referenceFrameLastName;

  public event EventHandler<PlacementSelectedAxisChangedEventArgs> ManipulatorAxisChanged;

  public CApRJRobotJogManipulationLogic(
    ITxObject manipulatedObject,
    UpdateDelta updateDelta,
    ResetManipulatorControl resetManipulatorControl,
    ForceExit forceExit,
    TxObject_DeletedEventHandler objectDeleted)
  {
    this._forceExit = forceExit;
    this._robotsManager = CApRJSRobotsManager.the();
    this._robotsManager.OnMasterModeChanged += new CApRJSRobotsManager.MasterModeChanged(this.OnMasterModeChanged);
    this._cache = new CApRJRobotJogMovementCache(this);
    this._RobotConfigurations = new ObservableCollection<string>();
    this._RobotConfigurationsDict = new Dictionary<string, TxPoseData>();
    this._objectDeleted = objectDeleted;
    switch (manipulatedObject)
    {
      case TxRobot _:
        this.Robot = manipulatedObject as TxRobot;
        break;
      case ITxRoboticLocationOperation _:
        ITxRoboticLocationOperation locationOperation = manipulatedObject as ITxRoboticLocationOperation;
        this.Robot = locationOperation.ParentRoboticOperation.Robot as TxRobot;
        this.Location = locationOperation;
        break;
    }
    this.LeadingFrame = TxFrameEx.CreateFrame(new TxFrameCreationDataEx("", new TxTransformation(), true));
    this.LeadingFrame.Blank();
    this.FillRobotConfigurationList();
    this.AttachKinematicMovedHandler();
    this._updateDelta = updateDelta;
    this._resetManipulatorControl = resetManipulatorControl;
    this._manipulator = new TxPlacementManipulator();
    this._rotationCircle = new CApRJRobotJogRotationCircleManager();
    this._savedLocations = new TxTransformation[3];
    this._pathToRoot = new List<ITxObjectCollection>();
  }

  private bool SetLocation(ITxRoboticLocationOperation location)
  {
    if (location == null)
    {
      this._clipboard.Location = (ITxRoboticLocationOperation) null;
      this.RestoreRotatedTCPF();
      TxApplication.RefreshDisplay();
      return true;
    }
    if (!CApRJRobotJogUtilities.IsRoboticLocationOperationWithAssignedRobot((ITxObject) location) || location.ParentRoboticOperation.Robot != this.Robot)
    {
      int num = (int) CApRJRobotJogNotificationService.Notify(string.Format(RJRobotJogResources.LocationUnrelatedToRobotMessage, (object) ((ITxObject) location).Name, (object) ((TxBaseGeometryCreationObject) this.Robot).Name), RJRobotJogResources.LocationUnrelatedToRobotTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
      return false;
    }
    TxApplication.ActiveUndoManager.StartTransaction();
    this.IsLocationReached = this.JumpToLocation(location);
    TxApplication.ActiveUndoManager.EndTransaction();
    return this.IsLocationReached;
  }

  private bool JumpToLocation(ITxRoboticLocationOperation location)
  {
    this._followMode = new TxOlpRobotFollowMode(this.Robot);
    this._followMode.FollowMode = true;
    this._followMode.AllowGhostGun = false;
    this._followMode.ForceConfiguration = this.IsConfigurationLocked;
    this._followMode.AllowMountedWorkpiece = true;
    if (!this._followMode.SetGunAndRobotOnLocation(location))
    {
      int num = (int) CApRJRobotJogNotificationService.NotifyModal(string.Format(RJRobotJogResources.RobotJogRobotCannotReachErrorMessage, (object) ((TxBaseGeometryCreationObject) this.Robot).Name, (object) ((ITxObject) location).Name), RJRobotJogResources.RobotJogRobotCannotReachErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
      return false;
    }
    this._followMode.UseTaughtPose = false;
    this._clipboard.Location = location;
    this.RestoreRotatedTCPF();
    this.MoveTCPFToExternalGunTCPF();
    this.SetExternalAxes();
    TxApplication.RefreshDisplay();
    return true;
  }

  private void AttachKinematicMovedHandler()
  {
    if (TxRobot.op_Equality(this.Robot, (ITxObject) null))
      return;
    this.Robot.KinematicMoved += new TxDevice_KinematicMovedEventHandler(this.OnKinematicMoved);
    List<ITxDevice> itxDeviceList = new List<ITxDevice>();
    foreach (TxJoint externalAx in (Collection<ITxObject>) this.Robot.ExternalAxes)
    {
      if (!itxDeviceList.Contains(externalAx.Device))
      {
        itxDeviceList.Add(externalAx.Device);
        externalAx.Device.KinematicMoved += new TxDevice_KinematicMovedEventHandler(this.OnKinematicMoved);
      }
    }
  }

  private void DettachKinematicMovedHandler()
  {
    if (TxRobot.op_Equality(this.Robot, (ITxObject) null))
      return;
    this.Robot.KinematicMoved -= new TxDevice_KinematicMovedEventHandler(this.OnKinematicMoved);
    List<ITxDevice> itxDeviceList = new List<ITxDevice>();
    foreach (TxJoint externalAx in (Collection<ITxObject>) this.Robot.ExternalAxes)
    {
      if (!itxDeviceList.Contains(externalAx.Device))
      {
        itxDeviceList.Add(externalAx.Device);
        externalAx.Device.KinematicMoved -= new TxDevice_KinematicMovedEventHandler(this.OnKinematicMoved);
      }
    }
  }

  public CApRJRobotJogClipboard Clipboard => this._clipboard;

  public TxRobot Robot
  {
    get => this.Clipboard.Robot;
    set
    {
      if (!TxRobot.op_Inequality(this.Clipboard.Robot, (ITxObject) value))
        return;
      this.UnRegisterForDeleteObjects();
      this.UnRegisterRobotAttachmentsForEvents();
      this.Clipboard.Robot = value;
      this.UpdateMovableObject();
      this.RegisterForDeleteObjects();
      this.RegisterRobotAttachmentsForEvents();
    }
  }

  public bool IsRobotBaseAtAbsoluteLocation => this.Clipboard.IsRobotBaseAtAbsoluteLocation;

  public ITxRoboticLocationOperation Location
  {
    get => this.Clipboard.Location;
    set
    {
      if (this.Clipboard.Location == value)
        return;
      this.UnRegisterForDeleteObjects();
      this._ignoreKinematicMovedEvent = true;
      this.IsLocationReached = true;
      bool flag = this.SetLocation(value);
      if (flag)
        this.GetRobotConfiguration();
      if (!this.IsLocationReached && this.Location != null && !((ITxObject) this.Location).IsValid())
      {
        this.IsLocationReached = true;
        flag = this.SetLocation((ITxRoboticLocationOperation) null);
      }
      if (flag)
        this.UpdateTcpfMovability();
      this._ignoreKinematicMovedEvent = false;
      this.RegisterForDeleteObjects();
      this.OnPropertyChanged(nameof (Location));
    }
  }

  public bool IsTcpfMovable
  {
    get => this._isTcpfMovable;
    set
    {
      this._isTcpfMovable = value;
      this.OnPropertyChanged(nameof (IsTcpfMovable));
    }
  }

  public bool LockTCPF
  {
    set
    {
      if (this._lockTCPF == value)
        return;
      this._lockTCPF = value;
      this.UpdateMovingObject();
    }
    get => this._lockTCPF;
  }

  public bool IsLocationReached { get; private set; }

  public bool EnableRobotPlacement
  {
    set
    {
      this._enableRobotPlacement = value;
      this.UpdateMovingObject();
    }
    get => this._enableRobotPlacement;
  }

  public bool MoveObjectsThatRobotIsAttachedTo
  {
    set
    {
      if (this._moveObjectsThatRobotIsAttachedTo == value)
        return;
      this._moveObjectsThatRobotIsAttachedTo = value;
      this.UpdateMovableObject();
    }
    get => this._moveObjectsThatRobotIsAttachedTo;
  }

  public bool IsConfigurationLocked
  {
    set
    {
      this._isConfigurationLocked = value;
      if (this._followMode == null)
        return;
      this._followMode.ForceConfiguration = value;
    }
    get => this._isConfigurationLocked;
  }

  public bool SetRobotExternalAxisInLocation { set; get; }

  public TxFrame ReferenceFrame
  {
    get => this._referenceFrame;
    set
    {
      if (TxFrame.op_Equality(this._referenceFrame, (ITxObject) value))
        return;
      this.ChangeManipulatorReferenceFrame(value);
      this._referenceFrame = value;
      if (TxFrame.op_Inequality(value, (ITxObject) null))
      {
        if (this._isFreezed)
          return;
        this.SetLeadingFrame();
        this._rotationCircle.ShowCircle(this.LeadingFrame.AbsoluteLocation, this.ReferenceFrame.AbsoluteLocation);
      }
      else
      {
        this._rotationCircle.HideCircle();
        this.IsManipulatorActive = false;
      }
    }
  }

  public bool IsMovedFromOutsideRJ
  {
    set => this._isObjectMovedFromOutside = value;
    get => this._isObjectMovedFromOutside;
  }

  public string SelectedConfiguration
  {
    set
    {
      this._selectedConfiguration = value;
      this.SetRobotConfiguration(this._selectedConfiguration);
    }
    get => this._selectedConfiguration;
  }

  public bool IsConfigurationReady { get; set; }

  public ObservableCollection<string> RobotConfigurations => this._RobotConfigurations;

  public ITxLocatableObject MovingObject
  {
    get => this._movingObject;
    set
    {
      if (this._movingObject == value)
        return;
      this._movingObject = value;
      this._isMovingObjectChanged = true;
      this.OnPropertyChanged(nameof (MovingObject));
    }
  }

  public ITxLocatableObject MovableObject { get; private set; }

  private TxFrame LeadingFrame { get; set; }

  public bool IsFullyInitialized { get; set; }

  public double RotationStepSize
  {
    get => this._rotationStepSize;
    set
    {
      this._rotationStepSize = value;
      if (this._manipulator == null || !this._isManipulatorActive)
        return;
      this._manipulator.RotationStepSize = this._rotationStepSize;
    }
  }

  public double TranslationStepSize
  {
    get => this._translationStepSize;
    set
    {
      this._translationStepSize = value;
      if (this._manipulator == null || !this._isManipulatorActive)
        return;
      this._manipulator.TranslationStepSize = this._translationStepSize;
    }
  }

  public bool SnapToStepSize
  {
    get => this._snapToStepSize;
    set
    {
      this._snapToStepSize = value;
      if (this._manipulator == null || !this._isManipulatorActive)
        return;
      this._manipulator.SnapByStepSize = this._snapToStepSize;
    }
  }

  public bool IsManipulationFromInsideCommand
  {
    get => this._isManipulationFromInsideCommand;
    set => this._isManipulationFromInsideCommand = value;
  }

  public bool IsManipulatorActive
  {
    get => this._isManipulatorActive;
    set
    {
      if (this._isManipulatorActive == value)
        return;
      this._isManipulatorActive = value;
      if (this._isManipulatorActive)
        this._isManipulatorActive = this.ActivateManipulator();
      else
        this.DeactivateManipulator();
    }
  }

  private void SetRobotConfiguration(string robotConfigurationString)
  {
    if (TxRobot.op_Equality(this.Robot, (ITxObject) null))
      return;
    if (string.IsNullOrEmpty(robotConfigurationString))
      return;
    try
    {
      this._ignoreKinematicMovedEvent = true;
      this.IsMovedFromOutsideRJ = false;
      TxApplication.ActiveUndoManager.StartTransaction();
      if (this._RobotConfigurationsDict.ContainsKey(robotConfigurationString))
        this.Robot.CurrentPose = this._RobotConfigurationsDict[robotConfigurationString];
      TxApplication.RefreshDisplay();
    }
    catch (Exception ex)
    {
      TxApplication.LogWriter.WriteExceptionLine(ex);
    }
    finally
    {
      TxApplication.ActiveUndoManager.EndTransaction();
      this.IsMovedFromOutsideRJ = true;
      this._ignoreKinematicMovedEvent = false;
      this.ChangeManipulatorReferenceFrame(this.ReferenceFrame, false);
    }
  }

  public void FillRobotConfigurationList()
  {
    this._RobotConfigurations.Clear();
    this._RobotConfigurationsDict.Clear();
    if (!TxRobot.op_Inequality(this.Robot, (ITxObject) null))
      return;
    this._ignoreKinematicMovedEvent = true;
    foreach (TxPoseData txPoseData in this.Location == null ? this.Robot.CalcInverseSolutions(new TxRobotInverseData(this.Robot.TCPF.AbsoluteLocation, (TxRobotInverseData.TxInverseType) 0)) : this.GetRobotInverseSolutionsAtLocation())
    {
      string configurationString = this._controllerUtils.GetConfigurationString(this.Robot.GetPoseConfiguration(txPoseData), (ConfigurationStringTypes) 2);
      if (!string.IsNullOrEmpty(configurationString) && !this._RobotConfigurationsDict.ContainsKey(configurationString))
      {
        this._RobotConfigurations.Add(configurationString);
        this._RobotConfigurationsDict.Add(configurationString, txPoseData);
      }
    }
    this.GetRobotConfiguration();
    this._ignoreKinematicMovedEvent = false;
  }

  private void GetRobotConfiguration()
  {
    if (TxRobot.op_Equality(this.Robot, (ITxObject) null))
      return;
    try
    {
      TxRobotConfigurationData poseConfiguration = this.Robot.GetPoseConfiguration(this.Robot.CurrentPose);
      if (poseConfiguration != null)
      {
        this._selectedConfiguration = this._controllerUtils.GetConfigurationString(poseConfiguration, (ConfigurationStringTypes) 2);
        if (!string.IsNullOrEmpty(this._selectedConfiguration) && !this._RobotConfigurations.Contains(this._selectedConfiguration))
          this._RobotConfigurations.Add(this._selectedConfiguration);
      }
      else
        this._selectedConfiguration = "";
      this.OnPropertyChanged("SelectedConfiguration");
      this.IsConfigurationReady = this._RobotConfigurations != null && this._RobotConfigurations.Count > 0;
      this.OnPropertyChanged("IsConfigurationReady");
    }
    catch (Exception ex)
    {
      TxApplication.LogWriter.WriteExceptionLine(ex);
    }
  }

  private ArrayList GetRobotInverseSolutionsAtLocation()
  {
    if (this.Location == null)
      return new ArrayList();
    try
    {
      ITxRoboticControllerServices controllerServices = this.GetControllerServices();
      return controllerServices == null ? new ArrayList() : controllerServices.CalculateInverseSolutions((ITxLocationOperation) this.Location, new TxJumpToLocationData(), (TxRobotInverseData.TxInverseType) 0);
    }
    catch (Exception ex)
    {
      TxApplication.LogWriter.WriteExceptionLine(ex);
    }
    return new ArrayList();
  }

  private ITxRoboticControllerServices GetControllerServices()
  {
    if (!(this._controllerUtils.GetInterfaceImplementationFromController(this.Robot.Controller.Name, typeof (ITxRoboticControllerServices), typeof (TxControllerAttribute), "ControllerName") is ITxRoboticControllerServices implementationFromController))
      implementationFromController = this._controllerUtils.GetInterfaceImplementationFromController("default", typeof (ITxRoboticControllerServices), typeof (TxControllerAttribute), "ControllerName") as ITxRoboticControllerServices;
    if (implementationFromController == null)
      return (ITxRoboticControllerServices) null;
    implementationFromController.Init(this.Robot);
    return implementationFromController;
  }

  private bool SetPose(ArrayList inverseSolutions)
  {
    if (inverseSolutions == null || inverseSolutions.Count == 0)
      return false;
    if (!this.IsConfigurationLocked)
    {
      this.Robot.CurrentPose = inverseSolutions[0] as TxPoseData;
      return true;
    }
    if (string.IsNullOrEmpty(this._selectedConfiguration))
      return false;
    foreach (TxPoseData inverseSolution in inverseSolutions)
    {
      if (this._controllerUtils.GetConfigurationString(this.Robot.GetPoseConfiguration(inverseSolution), (ConfigurationStringTypes) 2) == this._selectedConfiguration)
      {
        this.Robot.CurrentPose = inverseSolution;
        return true;
      }
    }
    return false;
  }

  public bool Manipulate(TxTransformation delta, TxTransformation referenceFrame = null)
  {
    if (TxTransformation.op_Equality(delta, new TxTransformation()) || this.MovingObject == null)
      return false;
    this.IsMovedFromOutsideRJ = false;
    this._ignoreKinematicMovedEvent = true;
    MovementAxis movementAxis = CApRJRobotJogRotationCircleManager.GetMovementAxis(delta);
    TxVector rotationRpyXyz = (referenceFrame ?? this.ReferenceFrame.AbsoluteLocation).RotationRPY_XYZ;
    if (this._robotsManager.GetRobotMasterSlaveMode() && this._robotsManager.IsMasterExist())
      this._robotsManager.RecordCurrentRobotData();
    TxUndoTransactionManagerExtension.StartCompactingTransaction(TxApplication.ActiveUndoManager, 2U);
    this.BeginDisableTCPTrackingMode();
    this.SaveExternalAxesData();
    this._cache.SetCachedState(movementAxis, rotationRpyXyz);
    delta = this._cache.GetCombinedDelta(delta);
    TxTransformation absoluteLocation = this.MovingObject.AbsoluteLocation;
    TxTransformation leadingObject = new TxTransformation(absoluteLocation.Translation, rotationRpyXyz, (TxTransformation.TxRotationType) 1);
    this._rotationCircle.ShowCircle(leadingObject, this.ReferenceFrame.AbsoluteLocation, delta);
    TxTransformation delta1;
    if (CApRJRobotJogRotationCircleManager.IsMovementRotation(this._rotationCircle.RotationAxis))
    {
      TxTransformation txTransformation = TxTransformation.op_Multiply(this._rotationCircle.RotationCenter, TxTransformation.op_Multiply(TxTransformation.op_Multiply(absoluteLocation.Inverse, this._rotationCircle.RotationCenter), delta.Inverse).Inverse);
      delta1 = TxTransformation.op_Multiply(absoluteLocation.Inverse, txTransformation);
    }
    else
    {
      TxTransformation txTransformation = TxTransformation.op_Multiply(leadingObject, delta);
      delta1 = new TxTransformation(TxTransformation.op_Multiply(absoluteLocation.Inverse, txTransformation).Translation, (TxTransformation.TxTransformationType) 1);
    }
    if (TxTransformation.op_Inequality(referenceFrame, (TxTransformation) null))
      this._rotationCircle.HideCircle();
    bool flag = this.ActualManipulate(delta1);
    if (flag)
    {
      this.LeadingFrame.AbsoluteLocation = new TxTransformation(this.MovingObject.AbsoluteLocation.Translation, this.ReferenceFrame.AbsoluteLocation.RotationRPY_XYZ, (TxTransformation.TxRotationType) 1);
      this._cache.Update(delta);
    }
    else
      this._cache.RestorePreviousState();
    this.RestoreExternalAxesData();
    this.EndDisableTCPTrackingMode();
    TxApplication.ActiveUndoManager.EndTransaction();
    this._ignoreKinematicMovedEvent = false;
    this.IsMovedFromOutsideRJ = true;
    this.UpdateManipulatorReferenceFrame(this.ReferenceFrame);
    if (flag)
      TxApplication.RefreshDisplay();
    return flag;
  }

  private bool ActualManipulate(TxTransformation delta)
  {
    TxTransformation oldMovableLocation = (TxTransformation) null;
    TxTransformation newTCPFLocation = (TxTransformation) null;
    this.GetRobotNewPosition(ref oldMovableLocation, ref newTCPFLocation, delta);
    bool flag1 = true;
    if (!this.LockTCPF && !CApRJRobotJogUtilities.IsLocationMovementValid(this.Location))
      flag1 = false;
    if (flag1)
      flag1 = this.SetTCPFPosition(newTCPFLocation);
    bool flag2 = true;
    if (flag1 && this._robotsManager.GetRobotMasterSlaveMode() && this._robotsManager.IsMasterExist())
      flag2 = this._robotsManager.UpdateSlaveRobots();
    if (!flag1 || !flag2)
    {
      this.RestoreOriginalPosition(oldMovableLocation, delta);
      if (!flag2)
        this.SetTCPFPosition(newTCPFLocation);
    }
    else if (!this.LockTCPF && this.Location != null && this.HasTaughtPose)
      this.UpdateTaughtPose();
    if (flag1)
      this.GetRobotConfiguration();
    return flag1 & flag2;
  }

  private void RestoreOriginalPosition(TxTransformation oldRobotLocation, TxTransformation delta)
  {
    if (this.LockTCPF)
    {
      this.MovableObject.AbsoluteLocation = oldRobotLocation;
    }
    else
    {
      if (this.Location == null)
        return;
      this.ManipulateLocatableObject(delta.Inverse, this.Location as ITxLocatableObject);
    }
  }

  private void GetRobotNewPosition(
    ref TxTransformation oldMovableLocation,
    ref TxTransformation newTCPFLocation,
    TxTransformation delta)
  {
    if (this.LockTCPF)
    {
      newTCPFLocation = this.Robot.TCPF.AbsoluteLocation;
      oldMovableLocation = this.MovableObject.AbsoluteLocation;
      if (this.IsRobotBaseAtAbsoluteLocation && !this.MoveObjectsThatRobotIsAttachedTo && this._clipboard.Equipment == null)
      {
        this.MovableObject.AbsoluteLocation = TxTransformation.op_Multiply(oldMovableLocation, delta);
      }
      else
      {
        TxTransformation absoluteLocation = this.Robot.Baseframe.AbsoluteLocation;
        this.MovableObject.AbsoluteLocation = TxTransformation.op_Multiply(TxTransformation.op_Multiply(TxTransformation.op_Multiply(absoluteLocation, delta), absoluteLocation.Inverse), oldMovableLocation);
      }
    }
    else if (this.Location != null)
      this.ManipulateLocatableObject(delta, this.Location as ITxLocatableObject);
    else
      newTCPFLocation = TxTransformation.op_Multiply(this.Robot.TCPF.AbsoluteLocation, delta);
  }

  private bool SetTCPFPosition(TxTransformation newTCPFLocation)
  {
    return this.Location == null ? this.SetPose(this.Robot.CalcInverseSolutions(new TxRobotInverseData(newTCPFLocation, (TxRobotInverseData.TxInverseType) 0))) : this._followMode.SetGunAndRobotOnLocation(this.Location);
  }

  internal void SaveOldLocations()
  {
    this._savedLocations[0] = this.MovableObject.AbsoluteLocation;
    this._savedLocations[1] = this.Robot.TCPF.AbsoluteLocation;
    if (this.Location == null)
      return;
    this._savedLocations[2] = (this.Location as ITxLocatableObject).AbsoluteLocation;
  }

  private void SaveExternalAxesData(bool manualSave = false)
  {
    if (this.Location == null)
      return;
    if (manualSave || !this.SetRobotExternalAxisInLocation)
    {
      TxRobotExternalAxisData[] externalAxesData = this.Location.RobotExternalAxesData;
      if (externalAxesData == null)
      {
        this._savedExternalAxisData = (TxRobotExternalAxisData[]) null;
      }
      else
      {
        this._savedExternalAxisData = new TxRobotExternalAxisData[externalAxesData.Length];
        for (int index = 0; index < externalAxesData.Length; ++index)
        {
          this._savedExternalAxisData[index] = new TxRobotExternalAxisData();
          this._savedExternalAxisData[index].Joint = externalAxesData[index].Joint;
          this._savedExternalAxisData[index].JointValue = externalAxesData[index].JointValue;
          this._savedExternalAxisData[index].Device = externalAxesData[index].Device;
        }
      }
    }
    this._followMode.SetRobotExternalAxesInLocation(this.Location);
  }

  private void RestoreExternalAxesData(bool manualRestore = false)
  {
    if (this.Location == null)
      return;
    if (this.SetRobotExternalAxisInLocation && !manualRestore)
    {
      this._followMode.SetRobotExternalAxesInLocation(this.Location);
    }
    else
    {
      this.Location.RobotExternalAxesData = this._savedExternalAxisData;
      this._savedExternalAxisData = (TxRobotExternalAxisData[]) null;
    }
  }

  internal bool JointJogManipulate(TxJoint joint)
  {
    bool disableTcpTrackingMode = this.ShouldDisableTCPTrackingMode;
    if (disableTcpTrackingMode)
      this.BeginDisableTCPTrackingMode();
    this._ignoreKinematicMovedEvent = true;
    if (this._robotsManager.GetRobotMasterSlaveMode() && this._robotsManager.IsMasterExist())
      this._robotsManager.RecordCurrentRobotData();
    TxUndoTransactionManagerExtension.StartCompactingTransaction(TxApplication.ActiveUndoManager, 2U);
    bool flag1 = true;
    string selectedConfiguration = this._selectedConfiguration;
    this._rotationCircle.HideCircle();
    this.SaveExternalAxesData(true);
    bool flag2;
    if (this.LockTCPF)
    {
      TxTransformation txTransformation1 = (TxTransformation) null;
      if (this.Location is ITxLocatableObject location && !this._savedLocations[2].Equals((object) location.AbsoluteLocation))
      {
        txTransformation1 = location.AbsoluteLocation;
        location.AbsoluteLocation = this._savedLocations[2];
      }
      if (((Collection<ITxObject>) this.Robot.ExternalAxes).Contains((ITxObject) joint))
      {
        TxTransformation absoluteLocation = this.Robot.TCPF.AbsoluteLocation;
        flag2 = this.SetTCPFPosition(this._savedLocations[1]);
        if (flag2 && this._robotsManager.GetRobotMasterSlaveMode() && this._robotsManager.IsMasterExist())
          this._robotsManager.UpdateSlaveRobots();
        if (!flag1)
          this.SetTCPFPosition(absoluteLocation);
      }
      else
      {
        flag2 = this.IsConfigurationPreserved(selectedConfiguration);
        TxTransformation absoluteLocation = this.MovableObject.AbsoluteLocation;
        if (flag2)
        {
          TxTransformation txTransformation2 = TxTransformation.op_Multiply(TxTransformation.op_Multiply(this._savedLocations[1], this.Robot.TCPF.AbsoluteLocation.Inverse), this._savedLocations[0]);
          this.MovableObject.AbsoluteLocation = new TxTransformation(txTransformation2.Translation, txTransformation2.RotationRPY_XYZ, (TxTransformation.TxRotationType) 1);
        }
        if (flag2 && this._robotsManager.GetRobotMasterSlaveMode() && this._robotsManager.IsMasterExist())
          this._robotsManager.UpdateSlaveRobots();
        if (!flag1)
          this.MovableObject.AbsoluteLocation = absoluteLocation;
      }
      if (!flag2 && TxTransformation.op_Inequality(txTransformation1, (TxTransformation) null))
        location.AbsoluteLocation = txTransformation1;
    }
    else if (this.Location != null)
    {
      ITxLocatableObject location = this.Location as ITxLocatableObject;
      if (!this._savedLocations[2].Equals((object) location.AbsoluteLocation))
      {
        TxFrame activeGunTcpf = this.GetActiveGunTCPF();
        TxTransformation absoluteLocation = location.AbsoluteLocation;
        if (((ITxRoboticOperation) this.Location).IsMountedWorkpieceOperation && TxFrame.op_Inequality(activeGunTcpf, (ITxObject) null))
        {
          location.AbsoluteLocation = activeGunTcpf.AbsoluteLocation;
          flag2 = CApRJRobotJogUtilities.IsLocationMovementValid(this.Location);
          if (!flag2)
            location.AbsoluteLocation = absoluteLocation;
          else if (this.HasTaughtPose)
            this.UpdateTaughtPose();
        }
        else
          flag2 = this.SetTCPFPosition(location.AbsoluteLocation);
      }
      else
      {
        flag2 = this.IsConfigurationPreserved(selectedConfiguration);
        if (flag2)
        {
          TxFrame activeGunTcpf = this.GetActiveGunTCPF();
          TxTransformation absoluteLocation = location.AbsoluteLocation;
          location.AbsoluteLocation = !((ITxRoboticOperation) this.Location).IsMountedWorkpieceOperation || !TxFrame.op_Inequality(activeGunTcpf, (ITxObject) null) ? this.Robot.TCPF.AbsoluteLocation : activeGunTcpf.AbsoluteLocation;
          flag2 = CApRJRobotJogUtilities.IsLocationMovementValid(this.Location);
          if (!flag2)
            location.AbsoluteLocation = absoluteLocation;
          else if (this.HasTaughtPose)
            this.UpdateTaughtPose();
        }
      }
    }
    else
      flag2 = this.IsConfigurationPreserved(selectedConfiguration);
    this.RestoreExternalAxesData(!flag2);
    TxApplication.ActiveUndoManager.EndTransaction();
    if (flag2)
      this.GetRobotConfiguration();
    this._ignoreKinematicMovedEvent = false;
    if (disableTcpTrackingMode)
      this.EndDisableTCPTrackingMode();
    return flag2 & flag1;
  }

  private bool MoveLocation(ITxRoboticLocationOperation locationToMove, TxTransformation position)
  {
    if (locationToMove == null || TxTransformation.op_Equality(position, (TxTransformation) null) || !CApRJRobotJogUtilities.IsMovableLocation(locationToMove) || !(locationToMove is ITxLocatableObject itxLocatableObject))
      return false;
    TxTransformation absoluteLocation = itxLocatableObject.AbsoluteLocation;
    TxApplication.ActiveUndoManager.StartTransaction();
    itxLocatableObject.AbsoluteLocation = position;
    bool flag = CApRJRobotJogUtilities.IsLocationMovementValid(locationToMove);
    if (flag)
      TxApplication.RefreshDisplay();
    else
      itxLocatableObject.AbsoluteLocation = absoluteLocation;
    TxApplication.ActiveUndoManager.EndTransaction();
    return flag;
  }

  public bool MoveLocationToTCPF(ITxRoboticLocationOperation locationToMove)
  {
    if (locationToMove == null)
      return false;
    if (!((ITxRoboticOperation) locationToMove).IsMountedWorkpieceOperation)
      return this.MoveLocation(locationToMove, this.Robot.TCPF.AbsoluteLocation);
    TxTransformation absoluteLocation = this.GetActiveGunTCPF(locationToMove)?.AbsoluteLocation;
    return this.MoveLocation(locationToMove, absoluteLocation);
  }

  private bool IsConfigurationPreserved(string lockedConfiguration)
  {
    if (!this._isConfigurationLocked)
      return true;
    string str = "";
    TxRobotConfigurationData poseConfiguration = this.Robot.GetPoseConfiguration(this.Robot.CurrentPose);
    if (poseConfiguration != null)
      str = this._controllerUtils.GetConfigurationString(poseConfiguration, (ConfigurationStringTypes) 2);
    return str == lockedConfiguration;
  }

  internal void SetExternalAxes()
  {
    if (!this.SetRobotExternalAxisInLocation || this.Location == null)
      return;
    this._followMode.SetRobotExternalAxesInLocation(this.Location);
  }

  private void ManipulateLocatableObject(TxTransformation delta, ITxLocatableObject obj)
  {
    ITxLocatableObject itxLocatableObject = obj;
    itxLocatableObject.AbsoluteLocation = TxTransformation.op_Multiply(itxLocatableObject.AbsoluteLocation, delta);
  }

  private TxFrame GetActiveGunTCPF(ITxRoboticLocationOperation location)
  {
    ITxRoboticControllerServices controllerServices = this.GetControllerServices();
    if (controllerServices == null)
      return (TxFrame) null;
    return !(controllerServices.GetActiveGun((ITxLocationOperation) location) is ITxTool activeGun) ? (TxFrame) null : activeGun.TCPF;
  }

  private TxFrame GetActiveGunTCPF() => this.GetActiveGunTCPF(this.Location);

  private void MoveTCPFToExternalGunTCPF()
  {
    if (this.Location == null || !((ITxRoboticOperation) this.Location).IsMountedWorkpieceOperation)
      return;
    TxFrame activeGunTcpf = this.GetActiveGunTCPF();
    if (TxFrame.op_Equality(activeGunTcpf, (ITxObject) null))
      return;
    this._tcpfTxTransformationChange = TxTransformation.op_Multiply(this.Robot.TCPF.AttachmentParent.AbsoluteLocation.Inverse, this.Robot.TCPF.AbsoluteLocation);
    this.Robot.TCPF.AbsoluteLocation = activeGunTcpf.AbsoluteLocation;
  }

  private void RestoreRotatedTCPF()
  {
    if (TxRobot.op_Equality(this.Robot, (ITxObject) null) || TxTransformation.op_Equality(this._tcpfTxTransformationChange, (TxTransformation) null))
      return;
    this.Robot.TCPF.AbsoluteLocation = TxTransformation.op_Multiply(this.Robot.TCPF.AttachmentParent.AbsoluteLocation, this._tcpfTxTransformationChange);
    this._tcpfTxTransformationChange = (TxTransformation) null;
  }

  internal void UpdateTcpfMovability()
  {
    this.IsTcpfMovable = this.Location == null || CApRJRobotJogUtilities.IsMovableLocation(this.Location);
  }

  private bool HasTaughtPose
  {
    get
    {
      bool hasTaughtPose = false;
      if (this.Location != null && ITxRoboticLocationOperationEx.GetTaughtPose(this.Location) != null)
        hasTaughtPose = true;
      return hasTaughtPose;
    }
  }

  private void UpdateTaughtPose()
  {
    if (!this.Robot.UsesNumericInverse)
      return;
    ITxRoboticLocationOperationEx.SetTaughtPose(this.Location, this.Robot.CurrentPose);
  }

  public void HideCircle() => this._rotationCircle.HideCircle();

  internal void ShowCircle(MovementAxis axis)
  {
    this._rotationCircle.ShowCircle(this.LeadingFrame.AbsoluteLocation, this.ReferenceFrame.AbsoluteLocation, axis);
  }

  public void Reset()
  {
    this._rotationCircle.HideCircle();
    if (this.Location == null)
    {
      this._clipboard.ResetPositions();
    }
    else
    {
      this._ignoreKinematicMovedEvent = true;
      this._isAbsoluteLocationChangedFired = false;
      this._followMode.ResetLocationExternalAxisData(this.Location);
      this._clipboard.Reset();
      this._followMode.SetGunAndRobotOnLocation(this.Location);
      this._isAbsoluteLocationChangedFired = true;
      this.OnPropertyChanged("AbsoluteLocationChanged");
      this._ignoreKinematicMovedEvent = false;
    }
    this.FillRobotConfigurationList();
    TxGraphicViewerEx.RequireRefreshSynchronization();
    TxApplication.RefreshDisplay();
  }

  public void Terminate()
  {
    this.StopRunToCollision();
    this.DettachKinematicMovedHandler();
    this.UnRegisterForAbsoluteLocationChanged();
    this.UnRegisterForDeleteObjects();
    this.UnRegisterRobotAttachmentsForEvents();
    if (this._rotationCircle != null)
      this._rotationCircle.HideCircle();
    if (TxFrame.op_Inequality(this.LeadingFrame, (ITxObject) null))
    {
      this.IsManipulatorActive = false;
      this.LeadingFrame.Delete();
      this.LeadingFrame = (TxFrame) null;
    }
    this.RestoreRotatedTCPF();
    TxApplication.RefreshDisplay();
  }

  public void DeleteLeadingFrame()
  {
    if (!TxFrame.op_Inequality(this.LeadingFrame, (ITxObject) null))
      return;
    this.LeadingFrame.Delete();
    this.LeadingFrame = (TxFrame) null;
  }

  private void RefreshManipulator()
  {
    if (!this.IsFullyInitialized)
      return;
    this.IsManipulatorActive = false;
    this.IsManipulatorActive = true;
  }

  internal void UpdateMovingObjectForSlave()
  {
    if (this.MovingObject == null)
      return;
    this.UnRegisterForAbsoluteLocationChanged();
    this.MovingObject = (ITxLocatableObject) null;
    this.RegisterForAbsoluteLocationChanged();
  }

  internal void UpdateMovingObject()
  {
    ITxLocatableObject itxLocatableObject = (ITxLocatableObject) null;
    if (TxRobot.op_Inequality(this.Robot, (ITxObject) null))
    {
      if (!this.LockTCPF)
        itxLocatableObject = (ITxLocatableObject) this.Robot.TCPF;
      else if (this.EnableRobotPlacement)
        itxLocatableObject = (ITxLocatableObject) this.Robot.Baseframe;
    }
    else
      itxLocatableObject = this.Location as ITxLocatableObject;
    if (this.MovingObject == itxLocatableObject)
      return;
    this.UnRegisterForAbsoluteLocationChanged();
    this.MovingObject = itxLocatableObject;
    this.RegisterForAbsoluteLocationChanged();
  }

  internal void UpdateMovableObject()
  {
    if (!TxRobot.op_Inequality(this.Clipboard.Robot, (ITxObject) null))
      return;
    ITxLocatableObject itxLocatableObject = (ITxLocatableObject) null;
    if (this.Clipboard.Equipment != null)
      itxLocatableObject = this.Clipboard.Equipment as ITxLocatableObject;
    else if (this.MoveObjectsThatRobotIsAttachedTo && this.Clipboard.RobotAttachment != null)
      itxLocatableObject = this.Clipboard.RobotAttachment;
    if (itxLocatableObject == null)
      itxLocatableObject = (ITxLocatableObject) this.Robot;
    if (itxLocatableObject == this.MovableObject)
      return;
    this.MovableObject = itxLocatableObject;
    if (!this.IsManipulatorActive)
      return;
    this.RefreshManipulator();
    TxApplication.RefreshDisplay();
  }

  internal TxObjectList GetMovingObjects()
  {
    TxObjectList movingObjects = new TxObjectList();
    ITxLocatableObject itxLocatableObject = this.LockTCPF ? this.MovableObject : (ITxLocatableObject) this.Robot;
    ((Collection<ITxObject>) movingObjects).Add((ITxObject) itxLocatableObject);
    ((TxObjectList<ITxObject>) movingObjects).AddRange((TxObjectList<ITxObject>) CApRJRobotJogUtilities.GetAttachmentObjects(itxLocatableObject));
    if (this._robotsManager.GetRobotMasterSlaveMode())
    {
      foreach (TxRobot slaveRobot in (Collection<TxRobot>) this._robotsManager.GetSlaveRobots())
        ((TxObjectList<ITxObject>) movingObjects).AddRange((TxObjectList<ITxObject>) CApRJRobotJogUtilities.GetAttachmentObjects((ITxLocatableObject) slaveRobot));
    }
    int count = ((Collection<ITxObject>) movingObjects).Count;
    for (int index = 0; index < count; ++index)
    {
      ITxCable cableFromDescendant = TxFlxCableEx.GetCableFromDescendant(((Collection<ITxObject>) movingObjects)[index]);
      if (cableFromDescendant != null && !((Collection<ITxObject>) movingObjects).Contains((ITxObject) cableFromDescendant))
        ((Collection<ITxObject>) movingObjects).Add((ITxObject) cableFromDescendant);
    }
    return movingObjects;
  }

  private void DeactivateManipulator()
  {
    if (this._manipulator == null)
      return;
    this.UnRegisterManipulatorEvents();
    this._manipulator.Hide();
  }

  private bool ActivateManipulator()
  {
    if (this.MovingObject == null || TxFrame.op_Equality(this.LeadingFrame, (ITxObject) null))
      return false;
    this._placementParameters = new TxPlacementManipulatorParameters((ITxObject) this.MovingObject, (TxPlacementManipulatorPosition) 1);
    this._placementParameters.EnableDimOtherObjects = true;
    this._placementParameters.NonDimmableObjects = (TxObjectList<ITxObject>) this.GetMovingObjects();
    this._manipulator.Show(this._placementParameters);
    this._manipulator.RotationStepSize = this.RotationStepSize;
    this._manipulator.TranslationStepSize = this.TranslationStepSize;
    this._manipulator.SnapByStepSize = this.SnapToStepSize;
    this.ChangeManipulatorReferenceFrame(this.ReferenceFrame);
    this.RegisterManipulatorEvents();
    this._manipulator.SelectedElement = (TxPlacementManipulatorElement) 1;
    return true;
  }

  private void RegisterManipulatorEvents()
  {
    if (this._manipulator == null)
      return;
    this._manipulator.ManipulatorMoved += new TxPlacementManipulator_ManipulatorMovedEventHandler(this._manipulator_ManipulatorMoved);
    this._manipulator.ElementPicked += new TxPlacementManipulator_ElementPickedChangedEventHandler(this._manipulator_ElementPicked);
  }

  private void UnRegisterManipulatorEvents()
  {
    if (this._manipulator == null)
      return;
    this._manipulator.ManipulatorMoved -= new TxPlacementManipulator_ManipulatorMovedEventHandler(this._manipulator_ManipulatorMoved);
    this._manipulator.ElementPicked -= new TxPlacementManipulator_ElementPickedChangedEventHandler(this._manipulator_ElementPicked);
  }

  private void _manipulator_ElementPicked(
    object sender,
    TxPlacementManipulator_ElementPickedEventArgs args)
  {
    this.ManipulatorAxisChanged((object) this, new PlacementSelectedAxisChangedEventArgs(CApRJRobotJogUtilities.GetAxisByManipulatorElement(args.PickedElement)));
  }

  private void _manipulator_ManipulatorMoved(
    object sender,
    TxPlacementManipulator_ManipulatorMovedEventArgs args)
  {
    if (this.IsPlaneSelected())
    {
      this.Manipulate(args.DeltaTransformation);
      this._resetManipulatorControl();
    }
    else
      this._updateDelta(args.DeltaTransformation);
  }

  internal void UpdateManipulatorSelectedAxis(Axes axes)
  {
    if (this._manipulator == null || !this._manipulator.IsVisible)
      return;
    TxPlacementManipulatorElement manipulatorElementByAxis = CApRJRobotJogUtilities.GetManipulatorElementByAxis(axes);
    if (this._manipulator.SelectedElement == manipulatorElementByAxis)
      return;
    this._manipulator.SelectedElement = manipulatorElementByAxis;
  }

  private void UpdateReferenceFrameLastLocation(TxFrame value)
  {
    this.m_referenceFrameLastLocation = TxFrame.op_Inequality(value, (ITxObject) null) ? value.AbsoluteLocation : (TxTransformation) null;
    this.m_referenceFrameLastName = TxFrame.op_Inequality(value, (ITxObject) null) ? value.Name : (string) null;
  }

  internal void UpdateManipulatorReferenceFrame(TxFrame frame)
  {
    if (!TxFrame.op_Inequality(frame, (ITxObject) null) || !TxTransformation.op_Inequality(this.m_referenceFrameLastLocation, frame.AbsoluteLocation))
      return;
    this.UpdateReferenceFrameLastLocation(frame);
    if (this._manipulator == null || !this._manipulator.IsVisible || !TxFrame.op_Inequality(frame, (ITxObject) null) || this._isFreezed)
      return;
    this._manipulator.UpdateReferenceFrame(frame.Name, frame.AbsoluteLocation);
  }

  internal void ChangeManipulatorReferenceFrame(TxFrame newFrame, bool forceUpdate = true)
  {
    if (!TxFrame.op_Inequality(newFrame, (ITxObject) null) || !forceUpdate && !TxTransformation.op_Inequality(this.m_referenceFrameLastLocation, newFrame.AbsoluteLocation))
      return;
    if (this._manipulator != null && this._manipulator.IsVisible)
    {
      if (this.m_referenceFrameLastName != null)
        this._manipulator.RemoveReferenceFrame(this.m_referenceFrameLastName);
      if (TxFrame.op_Inequality(newFrame, (ITxObject) null) && !this._isFreezed)
      {
        this._manipulator.AddReferenceFrame(newFrame.Name, newFrame.AbsoluteLocation);
        this._manipulator.SelectReferenceFrame(newFrame.Name);
      }
    }
    this.UpdateReferenceFrameLastLocation(newFrame);
  }

  private void SetLeadingFrame()
  {
    this.LeadingFrame.AbsoluteLocation = new TxTransformation(this.MovingObject.AbsoluteLocation.Translation, this.ReferenceFrame.AbsoluteLocation.RotationRPY_XYZ, (TxTransformation.TxRotationType) 1);
    if (this._isMovingObjectChanged)
    {
      this._isMovingObjectChanged = false;
      this.RefreshManipulator();
    }
    if (TxUndoTransactionManagerEx.IsObserverRunningInUndoExecution())
      return;
    TxApplication.RefreshDisplay();
  }

  public bool RunToCollision(
    TxPlacementCollisionControlRunCollisionEventArgs args)
  {
    if (this._collisionLogic == null)
      this._collisionLogic = new CApRJRobotJogCollisionLogic(this.MovableObject);
    if (this._robotsManager.GetRobotMasterSlaveMode() && this._robotsManager.IsMasterExist())
      this._robotsManager.SaveCurrentPoseForAllSlaveRobots();
    this._currentRobotState = this._clipboard.GetRobotAndLocationState();
    this.IsManipulatorActive = false;
    bool collision = this._collisionLogic.RunToCollision(args, this.LockTCPF, this.EnableRobotPlacement);
    this.IsManipulatorActive = true;
    return collision;
  }

  public void StopRunToCollision()
  {
    if (this._collisionLogic == null)
      return;
    this._collisionLogic.StopRunToCollision();
  }

  public void RestoreRobotToPoseBeforeCollisionRun()
  {
    if (this._currentRobotState == null)
      return;
    this._ignoreKinematicMovedEvent = true;
    this._clipboard.SetRobotAndLocationState(this._currentRobotState);
    if (this._robotsManager.GetRobotMasterSlaveMode() && this._robotsManager.IsMasterExist())
    {
      this._robotsManager.UpdateSlaveRobots();
      this._robotsManager.UpdateCurrentPoseInAllSlaveRobots();
    }
    this.GetRobotConfiguration();
    this._ignoreKinematicMovedEvent = false;
    this._currentRobotState = (CApRJRobotState) null;
    TxGraphicViewerEx.RequireRefreshSynchronization();
  }

  public event PropertyChangedEventHandler PropertyChanged;

  private void OnPropertyChanged(string property)
  {
    if (this.PropertyChanged == null)
      return;
    this.PropertyChanged((object) this, new PropertyChangedEventArgs(property));
  }

  private void RegisterForAbsoluteLocationChanged()
  {
    ITxLocatableObject itxLocatableObject1 = (ITxLocatableObject) null;
    if (this.MovingObject != null)
      itxLocatableObject1 = this.MovingObject;
    else if (TxRobot.op_Inequality(this.Robot, (ITxObject) null))
      itxLocatableObject1 = (ITxLocatableObject) this.Robot;
    if (itxLocatableObject1 == null)
      return;
    itxLocatableObject1.AbsoluteLocationChanged += new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.AbsoluteLocationChanged);
    ITxObjectCollection collection = ((ITxObject) itxLocatableObject1).Collection;
    for (ITxLocatableObject itxLocatableObject2 = collection as ITxLocatableObject; itxLocatableObject2 != null && itxLocatableObject2 != TxApplication.ActiveDocument.PhysicalRoot; itxLocatableObject2 = collection as ITxLocatableObject)
    {
      if (this._pathToRoot != null)
        this._pathToRoot.Add(collection);
      collection.ItemsRemoved += new TxObjectCollection_ItemsRemovedEventHandler(this.collection_ItemsRemoved);
      collection.ItemsAdded += new TxObjectCollection_ItemsAddedEventHandler(this.collection_ItemsAdded);
      itxLocatableObject2.AbsoluteLocationChanged += new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.AbsoluteLocationChanged);
      collection = ((ITxObject) collection).Collection;
    }
  }

  private void collection_ItemsAdded(object sender, TxObjectCollection_ItemsAddedEventArgs args)
  {
    this._forceExit();
  }

  private void collection_ItemsRemoved(object sender, TxObjectCollection_ItemsRemovedEventArgs args)
  {
    this._forceExit();
  }

  private void UnRegisterForAbsoluteLocationChanged()
  {
    ITxLocatableObject itxLocatableObject = (ITxLocatableObject) null;
    if (this.MovingObject != null)
      itxLocatableObject = this.MovingObject;
    else if (TxRobot.op_Inequality(this.Robot, (ITxObject) null))
      itxLocatableObject = (ITxLocatableObject) this.Robot;
    if (itxLocatableObject == null)
      return;
    itxLocatableObject.AbsoluteLocationChanged -= new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.AbsoluteLocationChanged);
    if (this._pathToRoot == null)
      return;
    foreach (ITxObjectCollection objectCollection in this._pathToRoot)
    {
      objectCollection.ItemsRemoved -= new TxObjectCollection_ItemsRemovedEventHandler(this.collection_ItemsRemoved);
      objectCollection.ItemsAdded -= new TxObjectCollection_ItemsAddedEventHandler(this.collection_ItemsAdded);
      (objectCollection as ITxLocatableObject).AbsoluteLocationChanged -= new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.AbsoluteLocationChanged);
    }
    this._pathToRoot.Clear();
  }

  private void AbsoluteLocationChanged(
    object sender,
    TxLocatableObject_AbsoluteLocationChangedEventArgs args)
  {
    if (this.IsMovedFromOutsideRJ)
    {
      this.ExitFollowModeOnExternalChanges();
      if (this.MovingObject != null)
        this.LeadingFrame.AbsoluteLocation = new TxTransformation(this.MovingObject.AbsoluteLocation.Translation, this.ReferenceFrame.AbsoluteLocation.RotationRPY_XYZ, (TxTransformation.TxRotationType) 1);
    }
    if (!this._isAbsoluteLocationChangedFired || this.MovingObject == null)
      return;
    this.OnPropertyChanged(nameof (AbsoluteLocationChanged));
    if (!this.IsMovedFromOutsideRJ)
      return;
    this.UpdateManipulatorReferenceFrame(this.ReferenceFrame);
  }

  private void RegisterForLocationAbsoluteLocationChanged()
  {
    if (this.Location == null)
      return;
    (this.Location as ITxLocatableObject).AbsoluteLocationChanged += new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.LocationAbsoluteLocationChanged);
  }

  private void UnRegisterForLocationAbsoluteLocationChanged()
  {
    if (this.Location == null)
      return;
    (this.Location as ITxLocatableObject).AbsoluteLocationChanged -= new TxLocatableObject_AbsoluteLocationChangedEventHandler(this.LocationAbsoluteLocationChanged);
  }

  private void LocationAbsoluteLocationChanged(
    object sender,
    TxLocatableObject_AbsoluteLocationChangedEventArgs args)
  {
    this.ExitFollowModeOnExternalChanges();
  }

  private void ExitFollowModeOnExternalChanges(bool checkIgnoreKinematicMovedEvent = true)
  {
    if (checkIgnoreKinematicMovedEvent && this._ignoreKinematicMovedEvent || this._isManipulationFromInsideCommand || this.Location == null)
      return;
    this.Location = (ITxRoboticLocationOperation) null;
    this.OnPropertyChanged("FollowModeExitedFromOutsideRJ");
  }

  public void FrameOfReferenceChanged(TxFrame frameOfReference)
  {
    if (!this._isMovingObjectChanged && !TxFrame.op_Inequality(this.ReferenceFrame, (ITxObject) frameOfReference))
      return;
    this.ReferenceFrame = frameOfReference;
  }

  public void FrameOfReferenceLocationChanged(TxFrame frameOfReference)
  {
    if (this.ReferenceFrame.Equals((object) frameOfReference))
      return;
    this.ReferenceFrame = frameOfReference;
  }

  private void OnKinematicMoved(object sender, TxDevice_KinematicMovedEventArgs args)
  {
    if (this._ignoreKinematicMovedEvent)
      return;
    this._ignoreKinematicMovedEvent = true;
    if (!TxUndoTransactionManagerEx.IsObserverRunningInUndoExecution())
      this.ExitFollowModeOnExternalChanges(false);
    else
      this._resetManipulatorControl();
    if (!this._isManipulationFromInsideCommand)
    {
      string selectedConfiguration = this._selectedConfiguration;
      this.GetRobotConfiguration();
      if (this._isConfigurationLocked && this._selectedConfiguration != selectedConfiguration)
      {
        this.IsConfigurationLocked = false;
        this.OnPropertyChanged("ConfigurationChangedFromOutsideRJ");
      }
    }
    this._ignoreKinematicMovedEvent = false;
  }

  public void OnManipulationFromInternalCmd(bool isManipulationFromInsideCommand)
  {
    this._isManipulationFromInsideCommand = isManipulationFromInsideCommand;
  }

  private bool IsPlaneSelected()
  {
    if (!this._manipulator.IsVisible)
      return false;
    return this._manipulator.SelectedElement == 10 || this._manipulator.SelectedElement == 14 || this._manipulator.SelectedElement == 12;
  }

  private void attachment_AttachmentParentChanged(
    object sender,
    TxLocatableObject_AttachmentParentChangedEventArgs args)
  {
    if (!this.Clipboard.IsAttachmentChanged)
      return;
    this.UnRegisterRobotAttachmentsForEvents();
    this.Clipboard.UpdateRobotAttachment();
    this.RegisterRobotAttachmentsForEvents();
    this.UpdateMovableObject();
  }

  public void RegisterRobotAttachmentsForEvents()
  {
    foreach (ITxLocatableObject itxLocatableObject in this.Clipboard.RobotAttachmentsChain)
    {
      ((ITxObject) itxLocatableObject).Deleted += this._objectDeleted;
      itxLocatableObject.AttachmentParentChanged += new TxLocatableObject_AttachmentParentChangedEventHandler(this.attachment_AttachmentParentChanged);
    }
  }

  public void UnRegisterRobotAttachmentsForEvents()
  {
    foreach (ITxLocatableObject itxLocatableObject in this.Clipboard.RobotAttachmentsChain)
    {
      ((ITxObject) itxLocatableObject).Deleted -= this._objectDeleted;
      itxLocatableObject.AttachmentParentChanged -= new TxLocatableObject_AttachmentParentChangedEventHandler(this.attachment_AttachmentParentChanged);
    }
  }

  private void RegisterForDeleteObjects()
  {
    if (!TxRobot.op_Inequality(this.Robot, (ITxObject) null))
      return;
    ((TxBaseGeometryCreationObject) this.Robot).Deleted += this._objectDeleted;
  }

  private void UnRegisterForDeleteObjects()
  {
    if (!TxRobot.op_Inequality(this.Robot, (ITxObject) null))
      return;
    ((TxBaseGeometryCreationObject) this.Robot).Deleted -= this._objectDeleted;
  }

  private void OnMasterModeChanged()
  {
    if (!this.IsManipulatorActive || !this._robotsManager.IsMasterExist())
      return;
    this.RefreshManipulator();
    TxApplication.RefreshDisplay();
  }

  public void BeginDisableTCPTrackingMode()
  {
    if (!this.IsInDisableTCPTrackingMode)
      TxApplicationEx.PerformanceModeManager().BeginMode(new TxPerformanceModeEx((TxPerformanceModeType) 3));
    ++this._disableTcpTrackingModeCounter;
  }

  public void EndDisableTCPTrackingMode()
  {
    if (!this.IsInDisableTCPTrackingMode)
      return;
    --this._disableTcpTrackingModeCounter;
    if (this._disableTcpTrackingModeCounter != 0)
      return;
    TxApplicationEx.PerformanceModeManager().EndMode(new TxPerformanceModeEx((TxPerformanceModeType) 3));
  }

  public bool IsInDisableTCPTrackingMode => this._disableTcpTrackingModeCounter > 0;

  public bool ShouldDisableTCPTrackingMode => this.LockTCPF;
}
